package com.dongpu.springboot.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author biyuyang
 *
 *	通过配置文件中的配置信息在rabbitmq服务端创建队列
 *
 *  该配置类可以注入交换器Exchange和队列Queue和路由键RoutingKey及相对应的属性(达到和控制台操作一样的效果)
 *
 *  Broker: 它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输
 *  Exchange: 消息交换机,它指定消息按什么规则,路由到哪个队列
 *  Queue: 消息的载体,每个消息都会被投到一个或多个队列
 *  Binding: 绑定,它的作用就是把exchange和queue按照路由规则绑定起来
 *  Routing Key: 路由关键字,exchange根据这个关键字进行消息投递
 *  Vhost: 虚拟主机,一个broker里可以有多个Vhost,用作不用用户的权限分离
 *  Producer: 消息生产者,就是投递消息的程序
 *  Consumer: 消息消费者,就是接受消息的程序
 *  Channel: 消息通道,在客户端的每个连接里,可建立多个channel
 *
 */
@Configuration
public class RabbitMQConfig {

	@Value("${rabbit.address.updatequeuename}")
	private String addressUpdateQueue;

	@Value("${rabbit.address.insertqueuename}")
	private String addressInsertQueue;

	@Value("${rabbit.address.deletequeuename}")
	private String addressDeleteQueue;

	@Bean
	public Queue addressUpdateQueue() {
		return new Queue(addressUpdateQueue);
	}

	@Bean
	public Queue addressInsertQueue() {
		return new Queue(addressInsertQueue);
	}

	@Bean
	public Queue addressDeleteQueue() {
		return new Queue(addressDeleteQueue);
	}


	public static final String EXCHANGE_A = "direct_exchange";
	public static final String FANOUT_EXCHANGE = "fanout_exchange";
	public static final String EXCHANGE_C = "my-mq-exchange_C";


	public static final String QUEUE_A = "QUEUE_A";
	public static final String QUEUE_B = "QUEUE_B";
	public static final String QUEUE_C = "QUEUE_C";

	public static final String ROUTINGKEY_A = "spring-boot-routingKey_A";
	public static final String ROUTINGKEY_B = "spring-boot-routingKey_B";
	public static final String ROUTINGKEY_C = "spring-boot-routingKey_C";

	/**
	 * 针对消费者配置
	 * 1. 设置交换机类型
	 * 2. 将队列绑定到交换机
	 * 	FanoutExchange: 将消息分发到所有的绑定队列，无routingkey的概念(广播)
	 * 	HeadersExchange：通过添加属性key-value匹配
	 * 	DirectExchange:按照routingkey分发到指定队列
	 * 	TopicExchange:多关键字匹配
	 */
	@Bean
	public DirectExchange defaultExchange() {
		return new DirectExchange(EXCHANGE_A);
	}

	/**
	 * 获取队列A
	 */
	@Bean
	public Queue queueA() {
		return new Queue(QUEUE_A, true); //队列持久
	}

	/**
	 * 获取队列B
	 */
	@Bean
	public Queue queueB() {
		return new Queue(QUEUE_B, true); //队列持久
	}

	/**
	 * 获取队列C
	 */
	@Bean
	public Queue queueC() {
		return new Queue(QUEUE_C, true); //队列持久
	}

	@Bean
	public Binding binding() {
		return BindingBuilder.bind(queueA()).to(defaultExchange())
			.with(RabbitMQConfig.ROUTINGKEY_A);
	}

	@Bean
	public Binding bindingB() {
		return BindingBuilder.bind(queueB()).to(defaultExchange()).with(RabbitMQConfig.ROUTINGKEY_B);

	}

	//配置fanout_exchange
	@Bean
	FanoutExchange fanoutExchange() {
		return new FanoutExchange(RabbitMQConfig.FANOUT_EXCHANGE);
	}

	//把所有的队列都绑定到这个交换机上去
	@Bean
	Binding bindingExchangeA(Queue queueA,FanoutExchange fanoutExchange) {
		return BindingBuilder.bind(queueA).to(fanoutExchange);
	}
	@Bean
	Binding bindingExchangeB(Queue queueB, FanoutExchange fanoutExchange) {
		return BindingBuilder.bind(queueB).to(fanoutExchange);
	}
	@Bean
	Binding bindingExchangeC(Queue queueC, FanoutExchange fanoutExchange) {
		return BindingBuilder.bind(queueC).to(fanoutExchange);
	}
}